package com.java.study.boot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.ldap.repository.config.EnableLdapRepositories;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.query.ContainerCriteria;
import org.springframework.ldap.query.LdapQueryBuilder;

import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author yuansheng.xu
 */
@Configuration
@EnableLdapRepositories
public class LdapTemplateConfig {

    @Bean
    public ContextSource contextSource() {
        LdapContextSource ldapContextSource = new LdapContextSource();
        /*  域账号的域名 */
        ldapContextSource.setUrl("ldap://jinkosolar.cn:389");
        /* dc ：一条记录所属区域 (哪一颗树)  https://blog.csdn.net/caoyujiao520/article/details/82762097 */
        ldapContextSource.setBase("dc=jinkosolar,dc=cn");
        /*  用户名 */
        ldapContextSource.setUserDn("ldapuser@jinkosolar.cn");
        /*  密码 */
        ldapContextSource.setPassword("uxejuGdK391fq3Bt");
        return ldapContextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate(ContextSource contextSource) {
        LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
        ldapTemplate.setIgnorePartialResultException(true);
        return ldapTemplate;
    }


    private static LdapTemplate ldapTemplate;

    @Autowired
    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        LdapTemplateConfig.ldapTemplate = ldapTemplate;

    }

    public static boolean authenticate(String name, String passWord) {
        EqualsFilter filter = new EqualsFilter("sAMAccountName", name);
        return ldapTemplate.authenticate("", filter.toString(), passWord);
    }

    public static Optional<Map<String, String>> queryByName(String name, String... attributes) {
        ContainerCriteria base = LdapQueryBuilder.query().countLimit(1)
                .attributes("sAMAccountName", "name", "cn", "mail", "company", "pwdlastset", "displayname", "accountexpires").attributes(attributes).
                        where("objectclass").is("person")
                .and("sAMAccountName").is(name);
        List<Map<String, String>> search = ldapTemplate.search(base, (AttributesMapper) ctx -> {
            NamingEnumeration<? extends Attribute> all = ctx.getAll();
            Map<String, String> map = new HashMap<>(ctx.size());
            while (all.hasMore()) {
                Attribute next = all.next();
                map.put(next.getID(), next.get().toString());
            }
            return map;
        });
        return Optional.ofNullable(search.get(0));
    }
}
